package com.keeper.mybatis.plugin;

import java.util.List;
import java.util.Properties;

import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

/**
 * @author chen.pian
 */
public class CustomPlugin extends PluginAdapter {

	private FullyQualifiedJavaType serializable;

	public CustomPlugin() {
		serializable = new FullyQualifiedJavaType("java.io.Serializable");
	}

	@Override
	public void setProperties(Properties properties) {
		super.setProperties(properties);
		// removePrefix = (String) (properties.getProperty("removePrefix"));
	}

	/**
	 * 用于Dao的生成
	 * 
	 * @author chen.pian
	 * @param interfaze
	 * @param topLevelClass
	 * @param introspectedTable
	 * @return
	 */
	@Override
	public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		if (interfaze != null) {
			interfaze.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
			interfaze.addAnnotation("@Repository");
		}
		return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
	}

	@Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
		this.addOrderBy(element, introspectedTable);
		return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
	}

	/**
	 * 用于sqlMapper.xml的生成
	 * 
	 * @author chen.pian
	 * @param sqlMap
	 * @param introspectedTable
	 * @return
	 */
	@Override
	public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
		return super.sqlMapGenerated(sqlMap, introspectedTable);
	}

	/**
	 * @author chen.pian
	 * @param element
	 * @param introspectedTable
	 */
	public void addOrderBy(XmlElement element, IntrospectedTable introspectedTable) {
		List<IntrospectedColumn> introspectedColumnList = introspectedTable.getPrimaryKeyColumns();
		String orderByClause = "order by ${orderByClause} ${orderBy}";
		if (introspectedColumnList != null && introspectedColumnList.size() > 0) {
			orderByClause = orderByClause + "," + introspectedColumnList.get(0).getActualColumnName()+" desc";
		}
		List<Element> elementList = element.getElements();
		if (elementList != null && elementList.size() > 0) {
			Element ele = elementList.get(elementList.size() - 1);
			((XmlElement) ele).getElements().clear();
			TextElement textEle = new TextElement(orderByClause);
			((XmlElement) ele).getElements().add(textEle);
		}
	}

	@Override
	public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
		this.addOrderBy(element, introspectedTable);
		return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element, introspectedTable);
	}

	/**
	 * 用于model的生成
	 * 
	 * @author chen.pian
	 * @param topLevelClass
	 * @param introspectedTable
	 * @return
	 */
	@Override
	@SuppressWarnings("all")
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

		return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
	}

	/**
	 * 用于Example的生成
	 * 
	 * @author chen.pian
	 * @param topLevelClass
	 * @param introspectedTable
	 * @return
	 */
	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		topLevelClass.addImportedType(serializable);
		topLevelClass.addSuperInterface(serializable);
		// 设置serialVersionUID属性
		Field field = new Field();
		field.setFinal(true);
		field.setInitializationString("1L");
		field.setName("serialVersionUID");
		field.setStatic(true);
		field.setType(new FullyQualifiedJavaType("long"));
		field.setVisibility(JavaVisibility.PRIVATE);
		context.getCommentGenerator().addFieldComment(field, introspectedTable);
		topLevelClass.addField(field);
		// 设置orderBy属性
		field = new Field();
		field.setName("orderBy");
		field.setType(new FullyQualifiedJavaType("String"));
		field.setVisibility(JavaVisibility.PRIVATE);
		context.getCommentGenerator().addFieldComment(field, introspectedTable);
		topLevelClass.addField(field);
		// 设置setOrderBy方法
		Method method = new Method();
		method.setName("setOrderBy");
		method.setReturnType(new FullyQualifiedJavaType("void"));
		method.addParameter(new Parameter(new FullyQualifiedJavaType("String"), "orderBy"));
		method.addBodyLine("this.orderBy = orderBy;");
		method.setVisibility(JavaVisibility.PUBLIC);
		topLevelClass.addMethod(method);

		// 设置getOrderBy方法
		method = new Method();
		method.setName("getOrderBy");
		method.setReturnType(new FullyQualifiedJavaType("String"));
		method.addBodyLine("return orderBy;");
		method.setVisibility(JavaVisibility.PUBLIC);
		topLevelClass.addMethod(method);
		return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
	}

	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}

}
